package jmine.tec.security.josso.agent;

import java.util.HashMap;
import java.util.Map;

import jmine.tec.cache.ExpiringReference;
import bancosys.tec.persist.dao.BaseDAOFactory;
import bancosys.tec.security.authorization.Permission;
import bancosys.tec.security.impl.domain.Credential;
import bancosys.tec.security.impl.permission.parser.PermissionParser;

/**
 * PermissionParser que utiliza a propriedade permissionId como chave para buscar a permission equivalente no banco de dados.
 * 
 * @author lundberg
 */
public class DatabasePermissionParser implements PermissionParser {

    private BaseDAOFactory daoFactory;

    private long cacheDuration;

    private ExpiringReference<Map<String, Permission>> cache = null;

    /**
     * Construtor
     * 
     * @param daoFactory daoFactory
     * @param cacheDuration duração do cache, em milisegundos.
     */
    public DatabasePermissionParser(BaseDAOFactory daoFactory, long cacheDuration) {
        this.daoFactory = daoFactory;
        this.cacheDuration = cacheDuration;
    }

    /**
     * {@inheritDoc}
     */
    public Permission parse(String permission) {
        return this.getPermissions().get(permission);
    }

    /**
     * Obtém o mapa de permissões, construindo-o, caso necessário.
     * 
     * @return mapa de permissões
     */
    private Map<String, Permission> getPermissions() {
        Map<String, Permission> permissions = this.cache == null ? null : this.cache.getReferentOrNull();
        if (permissions == null) {
            permissions = new HashMap<String, Permission>();
            for (Credential credential : this.daoFactory.getGenericDAO(Credential.class).findAll()) {
                Permission permission = credential.createPermission();
                permissions.put(permission.getPermissionId(), permission);
            }
            this.cache = new ExpiringReference<Map<String, Permission>>(permissions, this.cacheDuration);
        }
        return permissions;
    }
}
